/******************************************************************************
  * @file    PT32X005_crc.c
  * @author  应用开发团队
  * @version V1.1.0
  * @date    2020/1/27
  * @brief    This file provides firmware functions to manage the following
  *          functionalities of the CRC peripheral:
  *           + Initialization and Configuration
  *           + Interrupts and flags management
  *
  *
  ******************************************************************************
  * @attention
  *
  *
  *****************************************************************************/

/* Includes ------------------------------------------------------------------*/
#include "PT32X005_crc.h"


/** @defgroup CRC
  * @brief CRC driver modules
  * @{
  */

/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/


/**
  * @brief  Initializes the CRC peripheral according to the specified parameters
  *         in the CRC_InitStruct.
  * @param  CRC_InitStruct: pointer to an CRC_InitTypeDef structure that contains
  *         the configuration information for the specified CRC peripheral.
  * @retval None
  */
void CRC_Init(CRC_InitTypeDef* CRC_InitStruct)
{
	u32 tmpreg = 0;
	/* Check the parameters */
	assert_param(IS_CRC_CIS_SEL(CRC_InitStruct->CRC_DIN_Width));
	assert_param(IS_CRC_SEED_VAL(CRC_InitStruct->CRC_Seed));
	assert_param(IS_FUNCTIONAL_STATE(CRC_InitStruct->Bit_Input_Reverse));
	assert_param(IS_FUNCTIONAL_STATE(CRC_InitStruct->Byte_Input_Reverse));
	assert_param(IS_FUNCTIONAL_STATE(CRC_InitStruct->Bit_Output_Reverse));
	assert_param(IS_CRC_POLY_VAL(CRC_InitStruct->CRC_Poly));
	/*  */
	tmpreg = CRC->CR;
	/*  */
	tmpreg &= (u32)~(u32)CRC_CR_MASK;
	/*  */
	tmpreg  |= ((u32)((CRC_InitStruct->CRC_DIN_Width)));
	tmpreg  |= ((u32)((CRC_InitStruct->Bit_Input_Reverse) << 0x03));
	tmpreg  |= ((u32)((CRC_InitStruct->Byte_Input_Reverse) << 0x04));
	tmpreg  |= ((u32)((CRC_InitStruct->Bit_Output_Reverse) << 0x05));
	/* Write to CRC CR */
	CRC->CR = tmpreg;
	CRC->SEED = CRC_InitStruct->CRC_Seed;
	CRC->POLY = CRC_InitStruct->CRC_Poly;
}

/**
  * @brief  Fills each CRC_InitStruct member with its default value.
  * @param  CRC_InitStruct: pointer to an CRC_InitTypeDef structure which will
  *         be initialized.
  * @retval None
  */
void CRC_StructInit(CRC_InitTypeDef* CRC_InitStruct)
{
	/* Initialize the CRC data input width */
	CRC_InitStruct->CRC_DIN_Width = CRC_CIS_16b;
	/* Initialize the CRC data input bit reverse function */
	CRC_InitStruct->Bit_Input_Reverse = DISABLE;
	/* Initialize the CRC data output bit reverse function */
	CRC_InitStruct->Bit_Output_Reverse = DISABLE;
	/* Initialize the CRC data input byte reverse function */
	CRC_InitStruct->Byte_Input_Reverse = ENABLE;
	/* Initialize the CRC POLY */
	CRC_InitStruct->CRC_Poly = CRC_CCITT_POLY;
	/* Initialize the CRC SEED */
	CRC_InitStruct->CRC_Seed = 0;
}


/**
  * @brief  Enables or disables the specified CRC peripheral.
  * @param  NewState: new state of the CRC peripheral.
  *          This parameter can be: ENABLE or DISABLE.
  * @retval None
  */
void CRC_Cmd(FunctionalState NewState)
{
	/* Check the parameters */
	assert_param(IS_FUNCTIONAL_STATE(NewState));
	if (NewState != DISABLE)
	{
		/* Enable the selected CRC peripheral */
		CRC->CR |= CRC_CR_CEN;
	}
	else
	{
		/* Disable the selected CRC peripheral */
		CRC->CR &= (u16)~((u16)CRC_CR_CEN);
	}
}

/**
  * @brief   Resets the Data Out registers.
  * @retval None
  */
void CRC_ResetDout(void)
{
	CRC->CR |= CRC_CR_CRS;
}


/**
  * @brief  Computes the 16-bit CRC of a given 16-bit data.
  * @param  CRC_Data: data half-word(16-bit) to compute its CRC
  * @retval 16-bit CRC
  */
u32 CRC_CalcCRC(u16 CRC_Data)
{
	CRC->DIN = (u16) CRC_Data;
	return (CRC->DOUT);
}


/**
  * @brief  Computes the 16-bit CRC of a given buffer of data word(16-bit).
  * @param  pBuffer: pointer to the buffer containing the data to be computed
  * @param  BufferLength: length of the buffer to be computed
  * @retval 16-bit CRC
  */
u32 CRC_CalcBlockCRC(u16 pBuffer[], u32 BufferLength)
{
	u32 index = 0;
	for(index = 0; index < BufferLength; index++)
	{
		CRC->DIN = pBuffer[index];
	}
	return (CRC->DOUT);
}



/**
  * @brief  Returns the current CRC value.
  * @param  None
  * @retval 16-bit CRC
  */
u32 CRC_GetCRC(void)
{
	return (CRC->DOUT);
}


/**
  * @}
  */

